/*
 * Toedo
 * Copyright (C) 2009-2010 J. Devauchelle and contributors.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * version 3 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

package org.toedo.gui.dialogs;

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.Iterator;

import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.TitleAreaDialog;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableItem;
import org.toedo.controllers.DataController;
import org.toedo.controllers.events.EventConstants;
import org.toedo.controllers.events.EventController;
import org.toedo.gui.actions.NewTagAction;
import org.toedo.gui.actions.DeleteTagAction;
import org.toedo.gui.translations.Messages;
import org.toedo.model.BaseNote;
import org.toedo.model.Tag;
import org.toedo.model.enums.SortDirection;

public class TagsManagementDialog extends TitleAreaDialog implements PropertyChangeListener {

	private BaseNote mBaseNote;
	private Table mTagsList;
	
	private boolean mIsStandalone;
	
	public TagsManagementDialog(Shell parentShell) {
		this(parentShell, null);
	}
	
	public TagsManagementDialog(Shell parentShell, BaseNote baseNote) {
		super(parentShell);
		mBaseNote = baseNote;
		mIsStandalone = (mBaseNote == null);
		EventController.getInstance().addGeneralEventsListener(this);
	}
	
	protected Control createContents(Composite parent) {
		Control contents = super.createContents(parent);
		
		return contents;
	}
	
	protected Control createDialogArea(final Composite parent) {
		setTitle(Messages.TagsManagementDialog_Title);
		if (!mIsStandalone) {
			setMessage(String.format(Messages.TagsManagementDialog_Message, mBaseNote.getTitle()));
		}
		
		Composite mainPanel = (Composite) super.createDialogArea(parent);
		
		mainPanel.setLayout(new GridLayout(1, false));
		
		GridData mainGD = new GridData(SWT.FILL, SWT.FILL, true, true);
		mainGD.heightHint = 300;
		mainPanel.setLayoutData(mainGD);
		
		Composite panel = new Composite(mainPanel, SWT.NONE);
		panel.setLayout(new GridLayout(2, false));
		panel.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
		
		int tagListFlags = SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL;
		if (!mIsStandalone) {
			tagListFlags = tagListFlags | SWT.CHECK;
		}		
		mTagsList = new Table(panel, tagListFlags);
		mTagsList.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
		
		if (!mIsStandalone) {
			mTagsList.addListener(SWT.Selection, new Listener() {
				public void handleEvent(Event event) {
					if (event.detail == SWT.CHECK) {					
						TableItem item = (TableItem) event.item;
						Tag tag = (Tag) item.getData();

						if (item.getChecked()) {
							DataController.getInstance().getProject().addTagToBaseNote(mBaseNote, tag);
						} else {
							DataController.getInstance().getProject().removeTagFromBaseNote(mBaseNote, tag);
						}
					}		
				}
			});
		}
		
		Composite btnGroup1 = new Composite(panel, SWT.NULL);		
		btnGroup1.setLayout(new GridLayout(1, false));
		GridData gd = new GridData();
		gd.verticalAlignment = SWT.TOP;
		btnGroup1.setLayoutData(gd);
		
		Button newTagBtn = new Button(btnGroup1, SWT.NONE);
		newTagBtn.setText(Messages.TagsManagementDialog_NewTagBtn);
		newTagBtn.setLayoutData(new GridData(SWT.FILL, SWT.NONE, true, false));
		newTagBtn.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent arg0) {
				new NewTagAction(parent.getShell()).run();
			}
		});
		
		Button deleteTagBtn = new Button(btnGroup1, SWT.NONE);
		deleteTagBtn.setText(Messages.TagsManagementDialog_DeleteTagBtn);
		deleteTagBtn.setLayoutData(new GridData(SWT.FILL, SWT.NONE, true, false));
		deleteTagBtn.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent arg0) {
				TableItem[] selection = mTagsList.getSelection();
				if ((selection != null) && 
						(selection.length > 0)) {
					new DeleteTagAction((Tag) selection[0].getData()).run();
				}
			}
		});
		
		fillList();
		
		return parent;
	}
	
	protected void createButtonsForButtonBar(Composite parent) {
		Button closeBtn = createButton(parent, IDialogConstants.CLOSE_ID, IDialogConstants.CLOSE_LABEL, true);
		
		closeBtn.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {				
				close();				
			}
		});
	}
	
	private void fillList() {
		mTagsList.removeAll();
		TableItem item;
		Tag tag;
		Iterator<Tag> iter = DataController.getInstance().getProject().getTagsList(SortDirection.EnAscending).iterator();
		while (iter.hasNext()) {
			tag = iter.next();
			item = new TableItem(mTagsList, SWT.NULL);
			item.setText(tag.getName());
			item.setData(tag);
			
			if (!mIsStandalone) {
				if (mBaseNote.getTagsList().contains(tag)) {
					item.setChecked(true);
				} else {
					item.setChecked(false);
				}
			}
		}
	}

	@Override
	public void propertyChange(PropertyChangeEvent arg0) {
		class RefreshViewer implements Runnable {
			public void run() {
				fillList();
			}
		}
		
		if ((arg0.getPropertyName().equals(EventConstants.EVT_NEW_TAG)) ||
				(arg0.getPropertyName().equals(EventConstants.EVT_DELETE_TAG))) {			
			Display.getDefault().asyncExec(new RefreshViewer());			
		}
		
	}
	
	public void dispose() {
		EventController.getInstance().removeGeneralEventsListener(this);
	}

}
